/**
 * FileName: NettyThreadPoolConfig
 * Author: Mr.Wang
 * Date: 2025/10/16 16:24
 * Description:
 * History:
 */
package org.test.device.config.poll;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author Mr.Wang
 * @create 2025/10/16
 * @since 1.0.0
 */
@Slf4j
@Configuration
public class NettyThreadPoolConfig {

    @Bean
    public ThreadPoolTaskExecutor nettyInitTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int cpuCoreNum = Runtime.getRuntime().availableProcessors();
        executor.setCorePoolSize(cpuCoreNum);
        executor.setMaxPoolSize((int) (cpuCoreNum * 1.5));
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("Netty-Task-");
        executor.setThreadFactory(runnable -> {
            Thread thread = new Thread(runnable);
            thread.setName(executor.getThreadNamePrefix() + thread.getId());
            // 未捕获异常处理：打印线程名+异常，便于定位问题
            thread.setUncaughtExceptionHandler((t, e) ->
                    log.error("[NettyThreadPoolConfig]线程[{}]执行任务时发生异常", t.getName(), e)
            );
            log.info("[NettyThreadPoolConfig]创建Netty任务线程：{}", thread.getName());
            return thread;
        });

        //拒绝策略
        executor.setRejectedExecutionHandler((r, executor1) -> {
            // 关键：用executor（ThreadPoolTaskExecutor）获取队列信息，无需强转
            log.error("[NettyThreadPoolConfig]任务执行被拒绝！" +
                            "当前活跃线程数：{}，" +
                            "队列已用容量：{}，" +
                            "队列总容量：{}，" +
                            "最大线程数：{}，" +
                            "建议检查任务并发量或调整线程池参数",
                    executor1.getActiveCount(),  // 原生ThreadPoolExecutor的方法，获取活跃线程数
                    executor.getQueueSize(),     // 用Spring的executor获取队列已用容量
                    executor.getQueueCapacity(), // 用Spring的executor获取队列总容量
                    executor1.getMaximumPoolSize()// 原生方法，获取最大线程数
            );
        });

        //初始化+日志记录：打印参数
        executor.initialize();
        log.info("[NettyThreadPoolConfig]初始化完成→核心线程数：{}，最大线程数：{}，队列容量：{}",
                executor.getCorePoolSize(),
                executor.getMaxPoolSize(),
                executor.getQueueCapacity());
        return executor;
    }
}